import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.*;

public class MultiDraw2 extends JApplet  {

	protected DrawingCanvas canvas;
	protected EventListener listener;
	protected boolean isApplet = false;
	protected LinkedList ShapeObjects;
	protected MDUser mdUser;
	public ToolList toolList;
	public ToolBar toolBar;
	public MenuBar menuBar;
	public Socket sock;
	public JMenu openMenu;
	public JMenu deleteMenu;
	public JMenu downloadMenu;
	public JFrame open_delete_download_Frame;
	public JComboBox open_delete_download_Box;
	public int open0_delete1_download2_toggle = -1;
	
	public ArrayList<JButton> toolbuttonlist;
	public ControlPanel controlPanel;
	public String hostname;
	public int port = 8888;
	public PrintWriter remoteOut;
	public Scanner remoteIn;
	public String ownerOfControl = "";
	public boolean toolbarintialized = false;
	public String userName, userPass = "";
	
  /* Constructors */

  public MultiDraw2(boolean isApplet) {
	  this.isApplet = isApplet;
	    if (!isApplet) {
	      init();
	    }
  }

  public MultiDraw2() {
  /* invoked as Applet */
    this(true);
  }

  public void init()
  {
	  hostname = JOptionPane.showInputDialog("Please enter the IPAddress of your collaboration\n" +
	  		"or type local if you are hosting your own collaboration:");
	// only change THIS when connecting to a remote server
//	hostname = "local";
//	  hostname = "128.255.44.135";
	if(userLogin())
		System.exit(0);
	  
  	ShapeObjects = new LinkedList<ShapeObject>();
  	controlPanel = createControlPanel();
	mdUser = new MDUser(this);
	
    getContentPane().setLayout(new BorderLayout());
    
    canvas = createDrawingCanvas();
    canvas.setBackground(Color.white);
    getContentPane().add(canvas, BorderLayout.CENTER);
    
    listener = createDrawingCanvasListener(canvas);
    canvas.addDrawingCanvasListener(listener);
    canvas.addKeyListener((KeyListener)listener);
    getContentPane().add(controlPanel, BorderLayout.SOUTH);
    EventListener controlPanelListener = createControlPanelListener(canvas);
    controlPanel.addControlPanelListener(controlPanelListener);
    toolList = createToolList();
    while(toolbarintialized == false)
    {
    	toolBar = createToolBar(toolList);	
    	menuBar = createMenuBar(toolList);
    	toolbarintialized = true;
    }
    toolbuttonlist = toolBar.getToolButtonList();
    
    JMenu FileMenu = createFileMenu();
    JMenu ShareMenu = createShareMenu();
    getContentPane().add(toolBar, BorderLayout.WEST);
    menuBar.add(FileMenu);
    menuBar.add(ShareMenu);
    getContentPane().add (menuBar, BorderLayout.NORTH);
    getContentPane().add(mdUser, BorderLayout.EAST);
    canvas.setCurrentTool(new SelectTool(canvas, ShapeObjects, mdUser));
  		
    if(mdUser.usernameBox.getItemCount() == 0)
    	remoteOut.println("<<BRDCSTUSRLST>>");
    if(mdUser.ownerreceived == false)
    	remoteOut.println("<<RQSTOWNR>>");
  }
  /* Factory Methods  */
  protected void refreshShapeObjects(){
	  ShapeObjects.clear();
	  if(mdUser.ShapeObjects != null){
		  for(int i=0; i<mdUser.ShapeObjects.size(); i++)
		  {
	    	ShapeObjects.add(mdUser.ShapeObjects.get(i));
		  }
	  }
  }

  protected JMenu createShareMenu(){
	  JMenu shareMenu = new JMenu("Share");
	  JMenuItem shareTool = new JMenuItem("Share Tool");
	  shareTool.addActionListener(new ShareMenuItemListener(this,"shareTool"));
	  shareMenu.add(shareTool);
	  return shareMenu;
  }
  protected JMenu createFileMenu(){
	  JMenu fileMenu = new JMenu("Drawings");
	  JMenuItem NEW = new JMenuItem("New");
	  NEW.addActionListener(new DrawingMenuItemListener(this,"NEW"));
	  openMenu = new JMenu("Open");
	  openMenu.addMenuListener(new Open_DeleteMenuListener(this, "open"));
	  JMenuItem save = new JMenuItem("Save");
	  save.addActionListener(new DrawingMenuItemListener(this,"save"));
	  deleteMenu = new JMenu("Delete");
	  deleteMenu.addMenuListener(new Open_DeleteMenuListener(this,"delete"));
	  JMenuItem upload = new JMenuItem("Upload");
	  upload.addActionListener(new DrawingMenuItemListener(this,"upload"));
	  downloadMenu = new JMenu("Download");
	  downloadMenu.addMenuListener(new Open_DeleteMenuListener(this,"download"));
	  fileMenu.add(NEW);
	  fileMenu.add(openMenu);
	  fileMenu.add(save);
	  fileMenu.add(deleteMenu);
	  fileMenu.add(upload);
	  fileMenu.add(downloadMenu);
	  
	  return fileMenu;
  }

	protected ControlPanel createControlPanel() {
		return new ControlPanel();
	}
	
	protected EventListener createControlPanelListener(DrawingCanvas canvas) {
		return new ControlPanelListener(canvas, ShapeObjects);
	}
	
	static class AppCloser extends WindowAdapter  {
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}
  protected ToolBar createToolBar(ToolList toolList) {
    return new ToolBar(toolList);
  }

  protected MenuBar createMenuBar(ToolList toolList) {
    return new MenuBar(toolList);
  }

  protected DrawingCanvas createDrawingCanvas() {
    return new DrawingCanvas(this);
  }

  protected EventListener createDrawingCanvasListener(DrawingCanvas canvas) {
    return new DrawingCanvasListener(canvas);
  }

  /* Configure tool list used for ToolBar and MenuBar constructon */

  protected ToolList createToolList() {
    ToolList actions = new ToolList();
    actions.add(
    		new ToolListener("Select",
    		getImageIcon("select.jpg"),
    		"Select drawing tool",
    		canvas,
    		new SelectTool(canvas, ShapeObjects, mdUser)));
    actions.add(
                new ToolListener("Freehand",
	        getImageIcon("freehand.jpg"),
	        "freehand drawing tool",
	        canvas,
		new FreehandTool(canvas, ShapeObjects, mdUser)));
    actions.add(
		new ToolListener("Line",
		getImageIcon("line.jpg"),
		"Line drawing tool",
		canvas,
		new LineTool(canvas, ShapeObjects, mdUser)));
    actions.add(
		new ToolListener("Rectangle",
		getImageIcon("rectangle.jpg"),
		"Rectangle drawing tool",
		canvas,
		new RectangleTool(canvas, ShapeObjects, mdUser)));
    actions.add(
	        new ToolListener("Oval",
	        getImageIcon("oval.jpg"),
		"Oval drawing tool",
		canvas,
		new OvalTool(canvas, ShapeObjects, mdUser)));
    actions.add(
      		new ToolListener("Text",
      		getImageIcon("text.jpg"),
      		"text drawing tool",
              	canvas,
      		new TextTool(canvas, ShapeObjects, mdUser)));
    actions.add(
      		new ToolListener("Triangle",
      		getImageIcon("Triangle.jpg"),
      		"Triangle drawing tool",
              	canvas,
     		new TriangleTool(canvas, ShapeObjects, mdUser)));
    actions.add(
      		new ToolListener("Filled Oval",
      		getImageIcon("FilledOval.jpg"),
      		"Filled oval drawing tool",
              	canvas,
      		new FilledOvalTool(canvas, ShapeObjects, mdUser)));
    actions.add(
      		new ToolListener("Filled Triangle",
      		getImageIcon("FilledTriangle.jpg"),
      		"Filled triangle drawing tool",
              	canvas,
     		new FilledTriangleTool(canvas, ShapeObjects, mdUser)));
    return actions;
  }
  protected ImageIcon getImageIcon(String fileName) {
	   if(isApplet) {
	     try {
	       URL url = new URL(getCodeBase(), fileName);
	       return new ImageIcon(url);
	     }    catch(MalformedURLException e) {
	          return null;
	     }
	   }
	   else {
	      URL url = getClass().getResource(fileName);
	      return new ImageIcon(url);
	   }
	 }
  /* Main method (for invocation as Application only)  */
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setTitle("MultiDraw Fifth Iteration");
    frame.getContentPane().setLayout(new BorderLayout());
    frame.getContentPane().add(new MultiDraw2(false),
			      BorderLayout.CENTER);
    frame.addWindowListener(new AppCloser());
    frame.pack();
    frame.setSize(600, 400);
    frame.setVisible(true);
  }
  public boolean userLogin()
  {
	  boolean abort_flag;
	  int trial = 1;
	  while(true)
	  {
		  abort_flag = false;
		  if(trial > 1)
			  JOptionPane.showMessageDialog(this, "Invalid username or password");
		  userName = JOptionPane.showInputDialog("Please provide your username:");
		
		  if(!"".equals(userName) && userName != null)
		  {
			  JPasswordField tPasswordField = new JPasswordField(10);
			  tPasswordField.setEchoChar('*');
			  JOptionPane.showMessageDialog ( null, tPasswordField, "Enter password", JOptionPane.OK_OPTION );
			  char[] chars = tPasswordField.getPassword();
			  userPass = new String(chars);
			  if("".equals(userPass) && userPass != null)
				  abort_flag = true;
		  }
		  else
			  abort_flag = true; // if username = null
		  if(abort_flag == true)
		  {
			  // abort the application
			  abort_flag = true;
			  break;
		  }
		  else
		  {
			  // check in file - 'MDUserCreds', if the credentials are correct
			  // if credentials are valid, break the loop
			  if(checkUserCredentials(userName, userPass)) 
				  break;
		  }
		  trial++;
	  }
	  return(abort_flag);
  }

  public boolean checkUserCredentials(String un, String up)
  {
	  try 
      {  
		  String serverName = hostname;
    	 if (hostname.equals("local")) 
    		 serverName = null;
         InetAddress serverAddr = InetAddress.getByName(serverName);
         sock = new Socket(serverAddr, port);
         
         remoteOut = new PrintWriter(sock.getOutputStream(),true);
         remoteOut.println(un + " " + up);
         remoteIn = new Scanner(sock.getInputStream());
         if(remoteIn.hasNextLine())
         {
        	 String response = remoteIn.nextLine();
        	 if("true".equals(response))
        		 return(true);
        	 else
        		 return(false); 
         }
      }
	  catch(IOException e)
	  {
		  e.printStackTrace(); 
	  }
	return(false);  
  }
  public void changeToolBehavior(boolean b)
  {
	   mdUser.passControl.setEnabled(b);
	   controlPanel.clearButton.setEnabled(b);
	   controlPanel.deleteButton.setEnabled(b);
	   if(toolbuttonlist != null)
	   {
		   for(int i = 0; i < toolbuttonlist.size(); i++)
		   {
			   ((JButton)toolbuttonlist.get(i)).setEnabled(b);
		   }
	   }
  }
}
